<!-- 角色权限分配弹窗 -->
<template>
  <ele-modal
    :width="460"
    title="分配权限"
    position="center"
    :model-value="modelValue"
    :body-style="{ padding: '12px 0 12px 22px' }"
    @update:model-value="updateModelValue"
  >
    <ele-loading
      :loading="authLoading"
      :style="{
        height: '560px',
        paddingRight: '22px',
        maxHeight: 'calc(100vh - 192px)',
        minHeight: '100px',
        overflow: 'auto',
      }"
    >
      <el-tree
        ref="treeRef"
        show-checkbox
        :data="authData"
        node-key="id"
        :default-expand-all="true"
        :default-checked-keys="checkedKeys"
      >
        <template #default="scope">
          <span style="line-height: 1.1">
            <el-icon
              v-if="scope.data.icon"
              :size="16"
              style="margin-right: 6px; vertical-align: -5px"
            >
              <component :is="scope.data.icon" />
            </el-icon>
            <span style="vertical-align: -2px">{{ scope.data.title }}</span>
          </span>
        </template>
      </el-tree>
    </ele-loading>
    <template #footer>
      <el-button @click="updateModelValue(false)">
        取消
      </el-button>
      <el-button type="primary" :loading="loading" @click="save">
        保存
      </el-button>
    </template>
  </ele-modal>
</template>

<script setup>
import { listRoleMenu, updateRoleMenu } from '@/api/system/role'
import { eachTree, toTree } from 'ele-admin-plus/es'

const props = defineProps({
  /** 弹窗是否打开 */
  modelValue: Boolean,
  /** 当前角色数据 */
  data: Object,
})

const emit = defineEmits(['update:modelValue'])

/** 树组件实例 */
const treeRef = ref(null)

/** 权限数据 */
const authData = ref([])

/** 权限数据请求状态 */
const authLoading = ref(false)

/** 提交状态 */
const loading = ref(false)

/** 角色权限选中的keys */
const checkedKeys = ref([])

/** 查询权限数据 */
function query() {
  authData.value = []
  checkedKeys.value = []
  if (!props.data)
    return

  authLoading.value = true
  listRoleMenu(props.data.id)
    .then((res) => {
      if (!res.success)
        return utils.message(res.msg, 'error')

      // 转成树形结构的数据
      authData.value = toTree({
        data: res.data,
        idField: 'id',
        parentIdField: 'pid',
      })
      // 回显选中的数据
      nextTick(() => {
        const cks = []
        eachTree(authData.value, (d) => {
          if (d.id && d.checked && !d.children?.length)
            cks.push(d.id)
        })
        checkedKeys.value = cks
      })
    })
    .finally(() => {
      authLoading.value = false
    })
}

/** 保存权限分配 */
function save() {
  loading.value = true
  const ids = [
    ...(treeRef.value?.getCheckedKeys?.() ?? []),
    ...(treeRef.value?.getHalfCheckedKeys?.() ?? []),
  ]
  updateRoleMenu(props.data?.id, ids)
    .then((res) => {
      utils.message(res.msg, res.success)
      if (res.success)
        updateModelValue(false)
    })
    .finally(() => {
      loading.value = false
    })
}

/** 更新modelValue */
function updateModelValue(value) {
  emit('update:modelValue', value)
}

watch(
  () => props.modelValue,
  (modelValue) => {
    if (modelValue)
      query()
  },
)
</script>
